#include <QtGui>
#include "valuesettingsform.h"
#include "../core/aprcfg.h"

// while dealing with bias value, the upper_value has no sence.
ValueSettingsForm::ValueSettingsForm(const QString &item_name, 
									 const QString &current_range,
									 para_attr_e   range_attr,
									 const QString &lower_value,
									 const QString &upper_value,
									 int   master_kind,
									 QWidget *parent)
	: QDialog(parent)
{
	master_kind_ = master_kind;
	ui.setupUi(this);
	okButton		= ui.okButton;
	cancelButton	= ui.cacelButton;
	rangeCombo		= ui.rangeCombo;
	upperFrame		= ui.upperFrame;
	upperPointLabel = ui.upperPointLabel;
	upperUnitLabel  = ui.upperUnitLabel;
	upperIntPlus	= ui.upperIntPlus;
	upperIntMinus	= ui.upperIntMinus;
	upperFraPlus	= ui.upperFraPlus;
	upperFraMinus	= ui.upperFraMinus;
	upperIntEdit	= ui.upperIntEdit;
	upperFraEdit	= ui.upperFraEdit;
	lowerFrame		= ui.lowerFrame;
	lowerPointLabel = ui.lowerPointLabel;
	lowerUnitLabel  = ui.lowerUnitLabel;
	lowerIntPlus	= ui.lowerIntPlus;
	lowerIntMinus	= ui.lowerIntMinus;
	lowerFraPlus	= ui.lowerFraPlus;
	lowerFraMinus	= ui.lowerFraMinus;
	lowerIntEdit	= ui.lowerIntEdit;
	lowerFraEdit	= ui.lowerFraEdit;
	deleteButton	= ui.deleteButton;
	numberButtons	= ui.numberButtons;

	the_range_attr = range_attr;

	upperIntEdit->setAlignment(Qt::AlignCenter);
	upperFraEdit->setAlignment(Qt::AlignCenter);
	lowerIntEdit->setAlignment(Qt::AlignCenter);
	lowerFraEdit->setAlignment(Qt::AlignCenter);

	// only line edit(s) shuold get focus !!
	rangeCombo->setFocusPolicy(Qt::NoFocus);
	upperIntPlus->setFocusPolicy(Qt::NoFocus);
	upperIntMinus->setFocusPolicy(Qt::NoFocus);
	upperFraPlus->setFocusPolicy(Qt::NoFocus);
	upperFraMinus->setFocusPolicy(Qt::NoFocus);
	lowerIntPlus->setFocusPolicy(Qt::NoFocus);
	lowerIntMinus->setFocusPolicy(Qt::NoFocus);
	lowerFraPlus->setFocusPolicy(Qt::NoFocus);
	lowerFraMinus->setFocusPolicy(Qt::NoFocus);
	deleteButton->setFocusPolicy(Qt::NoFocus);

	// ranges & unit
	QStringList ranges;
	int range_index = 0;
	if(0 == master_kind){
		AprCfg::getRangesByItem(item_name, range_attr, ranges);
		rangeCombo->addItems(ranges);	
		range_index = rangeCombo->findText(current_range);
		rangeCombo->setCurrentIndex(range_index);
		rangeChanged(current_range);
	}else if(1 == master_kind){		// ref vl
		ranges << "9.99mcd" << "99.9mcd" << "999mcd";
		rangeCombo->addItems(ranges);	
		range_index = rangeCombo->findText(current_range);
		rangeCombo->setCurrentIndex(range_index);
		rangeChanged(current_range);
	}else if(2 == master_kind){		// ref bias
//	{"1000nA"	,	PM_B999_nA	,PM_BRANGE_ATTR	,'I',	' '},
//	{"10.00uA"	,	PM_B9_99uA	,PM_BRANGE_ATTR	,'I',	' '},
//	{"100.0uA"	,	PM_B99_9uA	,PM_BRANGE_ATTR	,'I',	' '},
//	{"1000uA"	,	PM_B999_uA	,PM_BRANGE_ATTR	,'I',	' '},
//	{"10.00mA"	,	PM_B9_99mA	,PM_BRANGE_ATTR	,'I',	' '},
//	{"100.0mA"	,	PM_B99_9mA	,PM_BRANGE_ATTR	,'I',	' '},
//	{"10.00V"	,	PM_B9_99V	,PM_BRANGE_ATTR	,'V',	' '},
		if(item_name.contains("VLI")){
			ranges << "1000nA" << "10.00uA" << "100.0uA" << "1000uA" << "10.00mA" << "100.0mA";
		}else{
			ranges << "10.00V";
		}
		rangeCombo->addItems(ranges);	
		range_index = rangeCombo->findText(current_range);
		rangeCombo->setCurrentIndex(range_index);
		rangeChanged(current_range);
	}
	
//	}else if(2 == master_kind){		// ref bias
//		rangeCombo->addItems(ranges);	
//		range_index = rangeCombo->findText(current_range);
//		rangeCombo->setCurrentIndex(range_index);
//		rangeChanged(current_range);
//	}

	// lower part
	the_lower_value = lower_value.toDouble();
	int value_length = lower_value.length();
	int point_position     = lower_value.indexOf(tr("."));
	QString integer_string = lower_value.left(point_position);
	QString decimal_string = 
				lower_value.right(value_length - point_position - 1);
	
/*
	QString str = tr("12.11");
	int value_length = str.length();
	int point_position = str.indexOf(tr("."));
	QString integer_string = str.left(point_position);
	QString decimal_string = str.right(value_length - point_position - 1);
*/
	qDebug() << point_position;
	qDebug() << integer_string;
	qDebug() << decimal_string;

	// add '0's when it's short than max length
	int sub_zero_count = lowerIntEdit->maxLength() - integer_string.length();
	QString f_integer_string;
	for(int i = 0; i < sub_zero_count; ++i){
		f_integer_string += tr("0");
	}
	f_integer_string += integer_string;
	lowerIntEdit->setText(f_integer_string);

	sub_zero_count = lowerFraEdit->maxLength() - integer_string.length();
	for(int j = 0; j < sub_zero_count; ++j){
		decimal_string += tr("0");
	}
	lowerFraEdit->setText(decimal_string);
	
	// upper part
	if(PM_BRANGE_ATTR == range_attr && master_kind != 2){
		upperFrame->setVisible(false);
	}else{
//		if(master_kind == 2){
			
		
//		}else{


		the_upper_value = upper_value.toDouble();
		qDebug() << "the upper value =" << the_upper_value;

		value_length   = upper_value.length();
		point_position = upper_value.indexOf(tr("."));
//		if(point_position != -1){
		integer_string = upper_value.left(point_position);
		decimal_string = upper_value.right(value_length - point_position - 1);
//		}
		qDebug() << integer_string << "," << decimal_string;
		upperIntEdit->setText(integer_string);
		upperFraEdit->setText(decimal_string);

		// add '0's when it's short than max length, NOT TESTED!! BE WARE OF IT!!
		sub_zero_count = upperIntEdit->maxLength() - integer_string.length();
		f_integer_string.clear();
		for(int i = 0; i < sub_zero_count; ++i){
			f_integer_string += tr("0");
		}
		f_integer_string += integer_string;
		upperIntEdit->setText(f_integer_string);

		sub_zero_count = upperFraEdit->maxLength() - integer_string.length();
		for(int j = 0; j < sub_zero_count; ++j){
			decimal_string += tr("0");
		}
		upperFraEdit->setText(decimal_string);
		qDebug() << f_integer_string << "," << decimal_string;


//		}
	}

	QList<QAbstractButton *> buttons = numberButtons->buttons();
	QPushButton *button = NULL;
	for(int index = 0; index < buttons.count(); ++index){
		button = qobject_cast<QPushButton *>(buttons.at(index));
		button->setFocusPolicy(Qt::NoFocus);

		connect(button, SIGNAL(clicked()), this, SLOT(numberButtonsClicked()));
	}

	// set font size
	QFont font = this->font();
	font.setPixelSize(font.pointSize() * 4 / 3);
	setFont(font);

	setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
	showMaximized();

	connect(deleteButton, SIGNAL(clicked()), this, SLOT(numberButtonsClicked()));
	connect(rangeCombo, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(rangeChanged(const QString &)));
//	connect()
	connect(okButton, SIGNAL(clicked()), this, SLOT(dialogShouldReturn()));
	connect(cancelButton, SIGNAL(clicked()), this, SLOT(dialogShouldReturn()));
}



ValueSettingsForm::~ValueSettingsForm()
{
	delete okButton;
	delete cancelButton;
	delete rangeCombo;
	delete upperPointLabel;
	delete upperUnitLabel;
	delete upperIntPlus;
	delete upperIntMinus;
	delete upperFraPlus;
	delete upperFraMinus;
	delete upperIntEdit;
	delete upperFraEdit;
	delete upperFrame;
	delete lowerPointLabel;
	delete lowerUnitLabel;
	delete lowerIntPlus;
	delete lowerIntMinus;
	delete lowerFraPlus;
	delete lowerFraMinus;
	delete lowerIntEdit;
	delete lowerFraEdit;
	delete lowerFrame;
	delete deleteButton;

	QList<QAbstractButton *> buttons = numberButtons->buttons();
	QPushButton *button = NULL;
	for(int index = 0; index < buttons.count(); ++index){
		button = qobject_cast<QPushButton *>(buttons.at(index));
		delete button;
	}

	delete numberButtons;
}


QString ValueSettingsForm::getRangeString()
{
	return rangeCombo->currentText();
}


QString ValueSettingsForm::getUnitString()
{
	qDebug() << lowerUnitLabel->text();
	return lowerUnitLabel->text();
}


// when range changed, the unit, hilimit, lowlimit, step should change too!!
void ValueSettingsForm::rangeChanged(const QString &range_string)
{
//	qDebug() << "range changed";
	ushort range_code = 0;
	bool ok = AprCfg::getParamCodeByName(range_string, the_range_attr, range_code);
	const rng_tbl_s *range = AprCfg::getRangeByCode(range_code);

	qDebug() << ok;
	qDebug() << range_string << " " << range << range_code << the_range_attr;

	hilimit_value  = range->hilimit;
	lowlimit_value = range->lowlimit;
	step_value     = range->step;

	// change unit label text
	lowerUnitLabel->setText(range->unit);
	upperUnitLabel->setText(range->unit);

	// calculate and set the max length of each line edit

	int int_length = 0;
	double hilimit = hilimit_value;
	while(hilimit >= 1){
		hilimit /= 10;
		++int_length;
	}
	lowerIntEdit->setMaxLength(int_length);
	upperIntEdit->setMaxLength(int_length);

	int fra_length = 0;
	double step = step_value;
	while(step < 0.98){
		step *= 10;
		++fra_length;
	}
	lowerFraEdit->setMaxLength(fra_length);
	upperFraEdit->setMaxLength(fra_length);
	qDebug() << "max length = " << int_length << fra_length;
	
	bool visible = (fra_length != 0);
	lowerFraEdit->setVisible(visible);
	lowerFraPlus->setVisible(visible);
	lowerFraMinus->setVisible(visible);
	lowerPointLabel->setVisible(visible);
	upperFraEdit->setVisible(visible);
	upperFraPlus->setVisible(visible);
	upperFraMinus->setVisible(visible);
	upperPointLabel->setVisible(visible);

	int width = visible ? 110 : 250;
	lowerIntEdit->setFixedWidth(width);
	lowerIntPlus->setFixedWidth(width);
	lowerIntMinus->setFixedWidth(width);
	upperIntEdit->setFixedWidth(width);
	upperIntPlus->setFixedWidth(width);
	upperIntMinus->setFixedWidth(width);
}


void ValueSettingsForm::calculateValues()
{
	QString value_string;
	value_string = lowerIntEdit->text() + tr(".") + lowerFraEdit->text();
	the_lower_value = value_string.toDouble();	

	if(PM_MRANGE_ATTR == the_range_attr || master_kind_ == 2){
		value_string = upperIntEdit->text() + tr(".") + upperFraEdit->text();
		the_upper_value = value_string.toDouble();
	}
}


void ValueSettingsForm::numberButtonsClicked()
{
	QPushButton *button = qobject_cast<QPushButton *>(sender());
	QString button_text = button->text();
	qDebug() << button_text;

	QLineEdit *edit = NULL;
	edit = lowerIntEdit->hasFocus() ? lowerIntEdit : edit;
	edit = lowerFraEdit->hasFocus() ? lowerFraEdit : edit;
	edit = upperIntEdit->hasFocus() ? upperIntEdit : edit;
	edit = upperFraEdit->hasFocus() ? upperFraEdit : edit;
	qDebug() << edit;

	if(edit != NULL){
		QString edit_string = edit->text();
		int edit_string_len = edit_string.length();
		int cursor_position = edit->cursorPosition();
		QString left_string = edit_string.left(cursor_position);
		QString right_string = 
					edit_string.right(edit_string_len - cursor_position);
		int right_string_len = right_string.length();

		qDebug() << edit_string;
		qDebug() << edit_string_len;
		qDebug() << cursor_position;
		qDebug() << left_string;
		qDebug() << right_string;

		QString edited_string;
		if(tr("<=") != button_text){
			// numbers

			qDebug() << left_string << "," << button_text << "," << right_string.right(right_string_len - 1);
			edited_string = left_string + button_text 
							+ right_string.right(right_string_len - 1);
			edit->setText(edited_string);
			edit->setCursorPosition(cursor_position + 1);
			qDebug() << cursor_position + 1 << ">>>>>>>>";
		}else{
			// backspace

			edited_string = left_string.left(cursor_position - 1) 
							+ tr("0") + right_string;
			edit->setText(edited_string);
			edit->setCursorPosition(cursor_position - 1);
		}

		calculateValues();
		if(the_lower_value < lowlimit_value || the_lower_value > hilimit_value){
			edit->setText(edit_string);
			edit->setCursorPosition(cursor_position + 1);
		}

		if(PM_MRANGE_ATTR == the_range_attr){
			if(the_upper_value < lowlimit_value 
				|| the_upper_value > hilimit_value){
//				|| the_upper_value < the_lower_value){
				edit->setText(edit_string);
				edit->setCursorPosition(cursor_position + 1);
			}
		}
	}
}



void ValueSettingsForm::spinButtonsClicked()
{

}




void ValueSettingsForm::dialogShouldReturn()
{
	QPushButton *button = qobject_cast<QPushButton *>(sender());
	if(button == okButton){
		calculateValues();
		if(the_upper_value < the_lower_value && the_range_attr == PM_MRANGE_ATTR){
			QMessageBox::warning(this, tr("Invalid Value Range"), tr("Lower Value Cannot Be Great Than Upper Value!"));
			return;
		}
		accept();
	}else{
		reject();
	}
}
